package com.eshanren.util;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class Ethipc {

    private static class ParallelReader extends Thread {

        private InputStream stream;
        private StringBuilder content = new StringBuilder();

        ParallelReader(InputStream stream) {
            this.stream = stream;
        }

        public String getContent() {
            return getContent(true);
        }

        public synchronized String getContent(boolean waitForComplete) {
            if (waitForComplete) {
                while (stream != null) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            return content.toString();
        }

        @Override
        public void run() {
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    content.append(line).append("\n");
                }
            } catch (IOException ioe) {
                ioe.printStackTrace();
            } finally {
                synchronized (this) {
                    stream = null;
                    notifyAll();
                }
            }
        }
    }


    public static class Result {
        public String errors;
        public String output;
        private boolean success = false;

        public Result(String errors, String output, boolean success) {
            this.errors = errors;
            this.output = output;
            this.success = success;
        }

        public boolean isFailed() {
            return !success;
        }
    }


    public String getBlance(String address, String contractAddress) {
        List<String> commandParts = new ArrayList<>();
//        commandParts.add(FileProperties.getGeth());
        commandParts.add("/cloud/eth/ipc.sh");
//        commandParts.add(FileProperties.getIpc());
        ProcessBuilder processBuilder = new ProcessBuilder(commandParts);

        try {
            Process process = processBuilder.start();

            try (BufferedWriter stream = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()))) {
                String contractAbi = "var abi=[{"
                        + "\"name\":\"balanceOf\","
                        + "\"constant\":true,"
                        + "\"payable\":false,"
                        + "\"type\":\"function\","
                        + "\"inputs\": [{\"name\":\"_owner\", \"type\":\"address\"}],"
                        + "\"outputs\":[{\"name\":\"balance\",\"type\":\"uint256\"}]}] \r\n";
                String string1 = "web3.eth.contract(abi).at(\"" + contractAddress + "\").balanceOf(\"" + address + "\") \r\n";
                stream.write(contractAbi);
                stream.write(string1);
                stream.flush();
            }

            ParallelReader error = new ParallelReader(process.getErrorStream());
            ParallelReader output = new ParallelReader(process.getInputStream());
            error.start();
            output.start();

            try {
                System.out.println("wait");
                process.waitFor();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }


            boolean success = process.exitValue() == 0;

            Result result = new Result(error.getContent(), output.getContent(), success);
            if (success) {
                System.out.println(result.output);
                return result.output;
            } else {
                System.out.println(result.errors);
                return result.errors;
            }

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    public static void main(String[] args) {
        List<String> commandParts = new ArrayList<>();
        commandParts.add("C:\\Users\\Administrator\\Desktop\\eth\\ethereum\\geth.exe");
        commandParts.add("attach");
        commandParts.add("ipc:\\\\.\\pipe\\geth.ipc");
        ProcessBuilder processBuilder = new ProcessBuilder(commandParts);

        try {
            Process process = processBuilder.start();

            try (BufferedWriter stream = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()))) {
                //stream.write("eth.getBlock(0x01) \r\n");
                String contractAbi = "var abi=[{"
                        + "\"name\":\"balanceOf\","
                        + "\"constant\":true,"
                        + "\"payable\":false,"
                        + "\"type\":\"function\","
                        + "\"inputs\": [{\"name\":\"_owner\", \"type\":\"address\"}],"
                        + "\"outputs\":[{\"name\":\"balance\",\"type\":\"uint256\"}]}] \r\n";
                String string1 = "web3.eth.contract(abi).at(\"0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0\").balanceOf(\"0x4D468cf47eB6DF39618dc9450Be4B56A70A520c1\") \r\n";
                stream.write(contractAbi);
                stream.write(string1);
                stream.flush();
            }

            ParallelReader error = new ParallelReader(process.getErrorStream());
            ParallelReader output = new ParallelReader(process.getInputStream());
            error.start();
            output.start();

            try {
                System.out.println("wait");
                process.waitFor();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }


            boolean success = process.exitValue() == 0;

            Result result = new Result(error.getContent(), output.getContent(), success);
            if (success) {
                System.out.println(result.output);
            } else {
                System.out.println(result.errors);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
